package com.banggood.upms.web;

import com.banggood.silk.web.api.common.PagedResult;
import com.banggood.silk.web.api.exception.SkbException;
import com.banggood.upms.bean.exception.ExceptionEnum;
import com.banggood.upms.bean.po.User;
import com.banggood.upms.bean.vo.PermissionVo;
import com.banggood.upms.bean.vo.SystemModuleVo;
import com.banggood.upms.bean.vo.SystemVo;
import com.banggood.upms.bean.vo.UserVo;
import com.banggood.upms.bean.vo.search.UserSearchCriteria;
import com.banggood.upms.bean.vo.validation.AddGroup;
import com.banggood.upms.bean.vo.validation.SearchGroup;
import com.banggood.upms.bean.vo.validation.UpdateGroup;
import com.banggood.upms.common.constant.StatusEnum;
import com.banggood.upms.common.constant.UpmsConstant;
import com.banggood.upms.service.UserScopeService;
import com.banggood.upms.service.UserService;
import com.banggood.upms.converter.UserConverter;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.util.List;

/**
 * @author XuChuangFeng
 */
@RequestMapping("/user")
@RestController
@Api(value = "用户管理", description = "用户管理")
public class UserController {

    protected final Log logger = LogFactory.getLog(getClass());
    @Autowired
    private UserService userService;
    @Autowired
    private UserScopeService userScopeService;
    @Autowired
    private UserConverter converter;

    @RequestMapping(value = "/search", method = RequestMethod.POST)
    @ApiOperation(value = "条件搜索用户", notes = "根据用户搜索条件返回用户列表", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "realName", value = "真实姓名", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "email", value = "邮箱", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "phone", value = "电话", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "gender", value = "性别", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "isActive", value = "是否激活", required = false, paramType = "query", dataType = "String", defaultValue = "1", allowableValues = "INACTIVE,ACTIVE"),
            @ApiImplicitParam(name = "scope", value = "用户域", required = true, paramType = "query", dataType = "String"),
    })
    @ApiResponses({
            @ApiResponse(code = 1005, message = "未传入用户域或用户一级域无效!")
    })
    public PagedResult<UserVo> search(@Validated({SearchGroup.class}) UserSearchCriteria criteria) throws Exception {
        if (!this.userScopeService.ifScopeKeyExist(criteria.getScope())) {
            throw new SkbException(ExceptionEnum.INVALIDATE_USER_SCOPE.getCode(), ExceptionEnum.INVALIDATE_USER_SCOPE.getMessage());
        }
        PageHelper.startPage(criteria.getPageNum(), criteria.getRows());
        List<User> users = userService.selectByCriteria(criteria);
        //取记录总条数
        long total = new PageInfo<>(users).getTotal();

        List<UserVo> userVos = converter.outputConverter(users);
        PagedResult<UserVo> result = new PagedResult<>(userVos, total);
        return result;
    }

    @RequestMapping(value = "/view", method = RequestMethod.GET)
    @ApiOperation(value = "根据用户ID获取用户详情", notes = "返回单个用户的数据", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "String"),
    })
    public UserVo selectByPrimaryKey(@RequestParam String id) throws Exception {
        User user = userService.selectByPrimaryKey(id);
        return user != null ? converter.singleOutputConverter(user) : null;
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ApiOperation(value = "添加用户", notes = "返回成功标志", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "accountName", value = "账号", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "realName", value = "真实姓名", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "email", value = "邮箱", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "phone", value = "电话", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "gender", value = "性别", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "isActive", value = "是否激活", required = false, paramType = "query", dataType = "String", defaultValue = "1", allowableValues = "INACTIVE,ACTIVE"),
            @ApiImplicitParam(name = "scope", value = "用户域", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "remark", value = "备注", required = false, paramType = "query", dataType = "String")
    })
    @ApiResponses({
            @ApiResponse(code = 1005, message = "无效的用户一级域!"),
            @ApiResponse(code = 4000, message = "账号已经存在！")
    })
    public String insert(@Validated({AddGroup.class}) UserVo vo) throws Exception {
        int count = userService.insert(converter.singleInputConverter(vo));
        if (count != 1) {
            throw new SkbException(ExceptionEnum.OPERATION_FAILED.getCode(), ExceptionEnum.OPERATION_FAILED.getMessage());
        }
        return UpmsConstant.SUCCESS;
    }

    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ApiOperation(value = "删除用户", notes = "返回成功或失败标志", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "String"),
    })
    public String deleteByPrimaryKey(@RequestParam String id) throws Exception {
        int count = userService.deleteByPrimaryKey(id);
        if (count != 1) {
            throw new SkbException(ExceptionEnum.OPERATION_FAILED.getCode(), ExceptionEnum.OPERATION_FAILED.getMessage());
        }
        return UpmsConstant.SUCCESS;
    }

    @RequestMapping(value = "/update", method = RequestMethod.POST)
    @ApiOperation(value = "更新操作", notes = "返回成功或失败标志", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "主键", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "realName", value = "真实姓名", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "email", value = "邮箱", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "phone", value = "电话", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "gender", value = "性别", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "password", value = "密码", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "isActive", value = "是否激活", required = false, paramType = "query", dataType = "String", allowableValues = "INACTIVE,ACTIVE"),
            @ApiImplicitParam(name = "scope", value = "用户域", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "remark", value = "备注", required = false, paramType = "query", dataType = "String")
    })
    @ApiResponses({
            @ApiResponse(code = 1005, message = "无效的用户一级域!")
    })
    public String updateByPrimaryKey(@Validated({UpdateGroup.class}) UserVo vo) throws Exception {
        if (!this.userScopeService.ifScopeKeyExist(vo.getScope())) {
            throw new SkbException(ExceptionEnum.INVALIDATE_USER_SCOPE.getCode(), ExceptionEnum.INVALIDATE_USER_SCOPE.getMessage());
        }
        int count = userService.updateByPrimaryKey(converter.singleInputConverter(vo));
        if (count != 1) {
            throw new SkbException(ExceptionEnum.OPERATION_FAILED.getCode(), ExceptionEnum.OPERATION_FAILED.getMessage());
        }
        return UpmsConstant.SUCCESS;
    }

    @GetMapping("/account-exists")
    @ApiOperation(value = "账号是否存在", notes = "账号是否存在", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "accountName", value = "账号是否存在", required = true, paramType = "query", dataType = "String"),
    })
    public String ifAccountNameExists(@RequestParam String accountName) {
        return userService.isAccountNameDuplicated(accountName) ? UpmsConstant.YES : UpmsConstant.NO;
    }

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    @ApiIgnore
    public SystemVo test() throws Exception {
        SystemVo systemVo = new SystemVo();
        systemVo.setName("财务系统");
        systemVo.setCode("Sellercube.Finance");

        SystemModuleVo module1 = new SystemModuleVo();
        module1.setName("用户模块");
        module1.setCode("Sellercube.Finance.UserController");
        systemVo.addModule(module1);

        PermissionVo p11 = new PermissionVo();
        p11.setName("财务系统-用户模块-新增");
        p11.setCode("Sellercube.Finance.UserController.add");
        p11.setStatus(StatusEnum.ACTIVE);
        module1.addPermission(p11);

        PermissionVo p12 = new PermissionVo();
        p12.setName("财务系统-用户模块-修改");
        p12.setCode("Sellercube.Finance.UserController.update");
        p12.setStatus(StatusEnum.ACTIVE);
        module1.addPermission(p12);

        SystemModuleVo module2 = new SystemModuleVo();
        module2.setName("营收模块");
        module2.setCode("Sellercube.Finance.RevenueController");
        systemVo.addModule(module2);

        PermissionVo p21 = new PermissionVo();
        p21.setName("财务系统-营收模块-新增");
        p21.setCode("Sellercube.Finance.RevenueController.add");
        p21.setStatus(StatusEnum.ACTIVE);
        module2.addPermission(p21);

        PermissionVo p22 = new PermissionVo();
        p22.setName("财务系统-营收模块-修改");
        p22.setCode("Sellercube.Finance.RevenueController.update");
        p22.setStatus(StatusEnum.ACTIVE);
        module2.addPermission(p22);

        return systemVo;
    }
}
